﻿using System;
using System.Collections;
using System.Security;
using CarlosAg.ExcelXmlWriter;


namespace QAHelper.Common
{
    public class ExcelLogger: ILogger
    {
        #region Properties and Variables

        string _testCaseName = string.Empty;
        string _logFileName = string.Empty;
        string _description = string.Empty;
        string _fileExtenstion = string.Empty;
        static ArrayList _logList = new ArrayList();

        public string ThisDateTime
        {
            set { ;}
            get { return DateTime.Now.ToString("dd/MM/yyyy hh:mm:ss"); }
        }

        public string TestCaseName
        {
            set { _testCaseName = value; }
            get { return _testCaseName;}
        }
        public string LogFileName
        {
            set { _logFileName = value; }
            get { return _logFileName; }
        }
        public string Description
        {
            set { _description = value; }
            get { return _description; }
        }
        public ArrayList LogList
        {
            set { _logList = value; }
            get { return _logList; }
        }
        #endregion

        #region Functions
        public void WriteStatus(string expected, string actual, string status, string verification_condition)
        {
            try
            {
                Test_Case testCase = new Test_Case();
                testCase.Test_Case_Name = this.TestCaseName;
                testCase.Expected_Result = expected;
                testCase.Actual_Result = actual;
                testCase.Logging_Time = ThisDateTime;
                testCase.Pass_Fail_Status = (string.IsNullOrEmpty(status)? GetStatus(actual,expected): status);
                testCase.Reason = "N/A";
                testCase.Verification_Condition = verification_condition;                
                LogList.Add(testCase);
            }
            catch (Exception exp)
            {
                Console.Write("Exception occured from Write Status: {0}", exp.Message);
            }

        }
        public void WriteStatus(string expected, string actual, string status, string verification_condition,string reason)
        {
            try
            {
                Test_Case testCase = new Test_Case();
                testCase.Test_Case_Name = this.TestCaseName;
                testCase.Expected_Result = expected;
                testCase.Actual_Result = actual;
                testCase.Logging_Time = ThisDateTime;
                testCase.Pass_Fail_Status = (string.IsNullOrEmpty(status) ? GetStatus(actual, expected) : status);
                testCase.Reason = reason;
                testCase.Verification_Condition = verification_condition;
                LogList.Add(testCase);
            }
            catch (Exception exp)
            {
                Console.Write("Exception occured from Write Status with reason: {0}", exp.Message);
            }
        }
        public void WriteStatus(TestCaseStructure testObj, string observed_result, string status, int rowIndex)
        {
            try
            {
                TestScenario tempDict = (TestScenario)testObj.TestScenarios[rowIndex-1];
                
                tempDict.ObservedResult = observed_result;
                tempDict.Status = status;                    
                testObj.TestScenarios[rowIndex-1] = tempDict;                
            }
            catch (Exception exp)
            {
                Console.Write("Exception occured from Write Status with reason: {0}", exp.Message);
            }
        }
        public void WriteLogIntoFile()
        {
            Workbook wBook = new Workbook();

            wBook.Properties.Author = "Sentrana_QA";
            Worksheet wSheet = wBook.Worksheets.Add("TestLog");


            // we can optionally set some column settings
            wSheet.Table.Columns.Add(new WorksheetColumn(150));
            wSheet.Table.Columns.Add(new WorksheetColumn(100));

            
            // Add some style
            WorksheetStyle headerStyle = wBook.Styles.Add("Header_Style");
            headerStyle.Font.Bold = true;

            WorksheetRow row = wSheet.Table.Rows.Add();
            row.Cells.Add("Test_Case_Name", DataType.String, "Header_Style");
            row.Cells.Add("Expected_Result", DataType.String, "Header_Style");
            row.Cells.Add("Actual_Result", DataType.String, "Header_Style");
            row.Cells.Add("Pass_Fail_Status", DataType.String, "Header_Style");
            row.Cells.Add("Verification_Condition", DataType.String, "Header_Style");
            row.Cells.Add("Reason", DataType.String, "Header_Style");
            row.Cells.Add("Logging_Time", DataType.String, "Header_Style");



            WorksheetStyle contentStyle = wBook.Styles.Add("content");            
            contentStyle.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            contentStyle.Alignment.Vertical = StyleVerticalAlignment.Top;
            contentStyle.Alignment.WrapText = true;

            ////wSheet.Table.Rows.Add(row);            
            foreach (Test_Case testCase in LogList)
            {
                WorksheetRow row_case = wSheet.Table.Rows.Add();
                row_case.Cells.Add(testCase.Test_Case_Name);
                row_case.Cells.Add(testCase.Expected_Result);
                row_case.Cells.Add(testCase.Actual_Result);
                row_case.Cells.Add(testCase.Pass_Fail_Status);
                row_case.Cells.Add(testCase.Verification_Condition);
                row_case.Cells.Add(testCase.Reason);
                row_case.Cells.Add(testCase.Logging_Time);
            }

            //// Save the file
            if (!this.LogFileName.Contains("."))
                this.LogFileName += this.LogFileName + ".xls";

            
            wBook.Save(this.LogFileName + "_" +DateTime.Now.ToString("dd-MM-yyy_hh-mm-ss") + ".xls");

        }

        public void WriteLogIntoFile(string workSheetName)
        {
            Workbook wBook = new Workbook();

            wBook.Properties.Author = "Sentrana_QA";
            Worksheet wSheet = wBook.Worksheets.Add(workSheetName);


            // we can optionally set some column settings
            wSheet.Table.Columns.Add(new WorksheetColumn(150));
            wSheet.Table.Columns.Add(new WorksheetColumn(100));


            // Add some style
            WorksheetStyle headerStyle = wBook.Styles.Add("Header_Style");
            headerStyle.Font.Bold = true;

            WorksheetRow row = wSheet.Table.Rows.Add();
            row.Cells.Add("Test_Case_Name", DataType.String, "Header_Style");
            row.Cells.Add("Expected_Result", DataType.String, "Header_Style");
            row.Cells.Add("Actual_Result", DataType.String, "Header_Style");
            row.Cells.Add("Pass_Fail_Status", DataType.String, "Header_Style");
            row.Cells.Add("Verification_Condition", DataType.String, "Header_Style");
            row.Cells.Add("Reason", DataType.String, "Header_Style");
            row.Cells.Add("Logging_Time", DataType.String, "Header_Style");



            WorksheetStyle contentStyle = wBook.Styles.Add("content");
            contentStyle.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            contentStyle.Alignment.Vertical = StyleVerticalAlignment.Top;
            contentStyle.Alignment.WrapText = true;

            ////wSheet.Table.Rows.Add(row);            
            foreach (Test_Case testCase in LogList)
            {
                WorksheetRow row_case = wSheet.Table.Rows.Add();
                row_case.Cells.Add(testCase.Test_Case_Name);
                row_case.Cells.Add(testCase.Expected_Result);
                row_case.Cells.Add(testCase.Actual_Result);
                row_case.Cells.Add(testCase.Pass_Fail_Status);
                row_case.Cells.Add(testCase.Verification_Condition);
                row_case.Cells.Add(testCase.Reason);
                row_case.Cells.Add(testCase.Logging_Time);
            }

            //// Save the file
            if (!this.LogFileName.Contains("."))
                this.LogFileName += this.LogFileName + "_" + DateTime.Now.ToString("dd-MM-yyy_hh-mm-ss") + ".xls";

            wBook.Save(this.LogFileName + "_"+DateTime.Now.ToString("dd-MM-yyy_hh-mm-ss")+ ".xls");


        }

        public void WriteLogIntoFile(TestCaseStructure testCaseObj, ArrayList headerList)
        {
            Workbook wBook = new Workbook();

            wBook.Properties.Author = "Sentrana_QA";
            Worksheet wSheet = wBook.Worksheets.Add(testCaseObj.TestCaseWorkSheetName);

            // Add some style
            WorksheetStyle headerStyle = wBook.Styles.Add("Header_Style");
            headerStyle.Font.Bold = true;

            WorksheetStyle summaryContentStyleDate = wBook.Styles.Add("SummaryContentStyleDate");
            summaryContentStyleDate.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            summaryContentStyleDate.Alignment.Vertical = StyleVerticalAlignment.Top;
            summaryContentStyleDate.Font.Bold = false;
            summaryContentStyleDate.Font.Size = 10;
            summaryContentStyleDate.Interior.Pattern = StyleInteriorPattern.None;
            summaryContentStyleDate.NumberFormat = "Short Date";            

            WorksheetStyle contentStyle = wBook.Styles.Add("content");
            contentStyle.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            contentStyle.Alignment.Vertical = StyleVerticalAlignment.Top;
            contentStyle.Alignment.WrapText = true;
            

            // we can optionally set some column settings
            wSheet.Table.Columns.Add(new WorksheetColumn(150));
            wSheet.Table.Columns.Add(new WorksheetColumn(100));

            WriteSummary(wBook, wSheet, testCaseObj.TestCaseSummary);
            WriteTestInfo(wBook, wSheet, testCaseObj.TestCaseInfo);
            WriteTestScenarioHeader(wBook, wSheet, headerList);
            WriteTestScenarios(wBook, wSheet, testCaseObj.TestScenarios);
            WriteTestCaseFooter(wBook, wSheet, testCaseObj);

            wBook.SpreadSheetComponentOptions.SpreadsheetAutoFit = true;
            
            wBook.Save(testCaseObj.TestLogFileName.Trim());
            
            


        }

        private string GetStatus(string actual, string expected)
        {
            if(actual.Equals(expected,StringComparison.InvariantCultureIgnoreCase))
                return "Pass";
            return "Fail";
        }

        #region Method to write summary portion

        private void WriteSummary(Workbook wb, Worksheet ws, ArrayList summaryContent)
        {
            WorksheetStyle summaryHeaderStyle = wb.Styles.Add("SummaryStyle");
            summaryHeaderStyle.Alignment.Horizontal = StyleHorizontalAlignment.Center;
            summaryHeaderStyle.Alignment.Vertical = StyleVerticalAlignment.Center;
            summaryHeaderStyle.Font.Bold = true;
            summaryHeaderStyle.Font.Size = 14;            
            summaryHeaderStyle.Interior.Color = "Gray";
            summaryHeaderStyle.Interior.Pattern = StyleInteriorPattern.Solid;

            WorksheetStyle summaryContentStyleBold = wb.Styles.Add("SummaryContentStyleBold");
            summaryContentStyleBold.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            summaryContentStyleBold.Alignment.Vertical = StyleVerticalAlignment.Top;
            summaryContentStyleBold.Font.Bold = true;
            summaryContentStyleBold.Font.Size = 10;
            summaryContentStyleBold.Interior.Pattern = StyleInteriorPattern.None;

            WorksheetStyle summaryContentStyleNormal = wb.Styles.Add("SummaryContentStyleNormal");
            summaryContentStyleNormal.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            summaryContentStyleNormal.Alignment.Vertical = StyleVerticalAlignment.Top;
            summaryContentStyleNormal.Font.Bold = false;
            summaryContentStyleNormal.Font.Size = 10;
            summaryContentStyleNormal.Interior.Pattern = StyleInteriorPattern.None;
            summaryContentStyleNormal.Alignment.ShrinkToFit = true;
            summaryContentStyleNormal.Alignment.WrapText = true;
            


            foreach (string str in summaryContent)
            {
                if (str.Equals("Summary"))
                {
                    WorksheetRow row = ws.Table.Rows.Add();
                    for (int i = 0; i < 6; i++)
                    {
                        row.Cells.Add();
                    }

                    row.Height = 39;
                    row.Cells[0].MergeAcross = 6;
                    row.Cells[0].Data.Text = str;
                    row.Cells[0].StyleID = "SummaryStyle";
                }
                else
                {
                    WorksheetRow row = ws.Table.Rows.Add();
                    for (int i = 0; i < 6; i++)
                    {
                        WorksheetCell cell = new WorksheetCell();                        
                        row.Cells.Add();
                    }
                    string[] rowContent = str.Split(';');

                    int cellIndex = 0;

                    foreach (string strContent in rowContent)
                    {
                        if (strContent.Contains("+"))
                        {
                            row.Cells[cellIndex].Data.Text = strContent.Split('+')[0];
                            if (strContent.Contains(":"))
                                row.Cells[cellIndex].StyleID = "SummaryContentStyleBold";
                            row.Cells[cellIndex+1].Data.Text = strContent.Split('+')[1];

                            if (strContent.Split('+')[0].ToLower().Contains("Last Updated".ToLower()))
                            {
                                row.Cells[cellIndex + 1].StyleID = "SummaryContentStyleDate";
                                row.Cells[cellIndex + 1].Data.Type = DataType.Number;
                            }
                            else
                                row.Cells[cellIndex + 1].StyleID = "SummaryContentStyleNormal";

                            cellIndex = cellIndex + 2;
                        }
                    }

                }
            }
        }

        #endregion

        #region Method to write test info portion

        private void WriteTestInfo(Workbook wb, Worksheet ws, ArrayList summaryContent)
        {
            WorksheetStyle summaryTestInfoStyle = wb.Styles.Add("TestInfoStyle");
            summaryTestInfoStyle.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            summaryTestInfoStyle.Alignment.Vertical = StyleVerticalAlignment.Center;
            summaryTestInfoStyle.Font.Bold = true;
            summaryTestInfoStyle.Font.Size = 14;
            summaryTestInfoStyle.Interior.Color = "Gray";
            summaryTestInfoStyle.Interior.Pattern = StyleInteriorPattern.Solid;



            foreach (string str in summaryContent)
            {
                if (str.Equals("Test Case"))
                {
                    WorksheetRow row = ws.Table.Rows.Add();
                    for (int i = 0; i < 6; i++)
                    {
                        row.Cells.Add();
                    }

                    row.Height = 43;
                    row.Cells[0].MergeAcross = 6;
                    row.Cells[0].Data.Text = str;
                    row.Cells[0].StyleID = "TestInfoStyle";
                }
                else
                {
                    WorksheetRow row = ws.Table.Rows.Add();
                    for (int i = 0; i < 6; i++)
                    {
                        WorksheetCell cell = new WorksheetCell();
                        row.Cells.Add();
                    }
                    string[] rowContent = str.Split(';');

                    int cellIndex = 0;

                    foreach (string strContent in rowContent)
                    {
                        if (strContent.Contains("+"))
                        {
                            row.Cells[cellIndex].Data.Text = strContent.Split('+')[0];
                            if (strContent.Contains(":"))
                                row.Cells[cellIndex].StyleID = "SummaryContentStyleBold";
                            row.Cells[cellIndex + 1].Data.Text = strContent.Split('+')[1];

                            if (strContent.Split('+')[0].ToLower().Contains("Last Updated".ToLower()))
                            {
                                row.Cells[cellIndex + 1].StyleID = "SummaryContentStyleDate";
                                row.Cells[cellIndex + 1].Data.Type = DataType.Number;
                            }
                            else
                                row.Cells[cellIndex + 1].StyleID = "SummaryContentStyleNormal";

                            cellIndex = cellIndex + 2;
                        }
                    }

                }
            }
        }

        #endregion

        #region Method to write test scenario header

        private void WriteTestScenarioHeader(Workbook wb, Worksheet ws, ArrayList headerList)
        {
            WorksheetStyle testScenarioHeaderStyle = wb.Styles.Add("TestCaseHeaderStyle");
            testScenarioHeaderStyle.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            testScenarioHeaderStyle.Alignment.Vertical = StyleVerticalAlignment.Center;
            testScenarioHeaderStyle.Font.Bold = true;
            testScenarioHeaderStyle.Font.Size = 10;
            testScenarioHeaderStyle.Interior.Color = "LightGray";
            testScenarioHeaderStyle.Interior.Pattern = StyleInteriorPattern.Solid;

            WorksheetRow row = ws.Table.Rows.Add();
            row.Height = 21;                
            foreach (string str in headerList)
            {
                WorksheetCell cell = new WorksheetCell();
                cell.Data.Text = str;                
                cell.Data.Text = str;
                cell.StyleID = "TestCaseHeaderStyle";
                row.Cells.Add(cell);                
            }                            
        }

        #endregion

        #region Method to write each test scenario with observed result and status

        private void WriteTestScenarios(Workbook wb, Worksheet ws, ArrayList testScenarios)
        {
            WorksheetStyle testScenarioStyle = wb.Styles.Add("TestCaseScenarioStyle");
            testScenarioStyle.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            testScenarioStyle.Alignment.Vertical = StyleVerticalAlignment.Top;
            testScenarioStyle.Font.Bold = false;
            testScenarioStyle.Alignment.ShrinkToFit = true;
            testScenarioStyle.Alignment.WrapText = true;
                      
            foreach (TestScenario testScenarioRow in testScenarios)
            {
                WorksheetRow row_case = ws.Table.Rows.Add();
                row_case.AutoFitHeight = true;
                
                
                WriteEachScenario(testScenarioRow.TestCaseID,row_case);
                WriteEachScenario(testScenarioRow.IsInAutomationScope, row_case);
                WriteEachScenario(testScenarioRow.Platform, row_case);
                WriteEachScenario(testScenarioRow.TestObjective, row_case);
                WriteEachScenario(testScenarioRow.TestSteps, row_case);
                WriteEachScenario(testScenarioRow.TestData, row_case);
                WriteEachScenario(testScenarioRow.ExpectedResult, row_case);
                WriteEachScenario(testScenarioRow.ReferenceImage, row_case);
                WriteEachScenario(testScenarioRow.ObservedResult, row_case);
                WriteEachScenario(testScenarioRow.Status, row_case);
                WriteEachScenario(testScenarioRow.BugImage, row_case);
                WriteEachScenario(testScenarioRow.CommentBUGID, row_case);
                WriteEachScenario(testScenarioRow.TestMethodName, row_case);

                //foreach (string testCell in testScenarioRow.)
                //{
                //}

            }
        }


        #endregion

        #region Method to write each test scenario with observed result and status

        private void WriteTestCaseFooter(Workbook wb, Worksheet ws, TestCaseStructure testObjParam)
        {
            WorksheetStyle testScenarioFooterStyle = wb.Styles.Add("TestCaseFooterStyle");
            testScenarioFooterStyle.Alignment.Horizontal = StyleHorizontalAlignment.Left;
            testScenarioFooterStyle.Alignment.Vertical = StyleVerticalAlignment.Top;
            testScenarioFooterStyle.Font.Bold = true;
            testScenarioFooterStyle.Font.Size = 10;            

            ws.Table.Rows.Add();
            ws.Table.Rows.Add();

            foreach (string testFooterRow in testObjParam.TestCaseFooter)
            {
                WorksheetRow row_case = ws.Table.Rows.Add();
                row_case.AutoFitHeight = true;
                
                string temp = testFooterRow;
                WorksheetCell cell = row_case.Cells.Add();               
                cell.Data.Text = temp;
                if (testFooterRow.Contains(":"))
                {
                    cell.StyleID = "TestCaseFooterStyle";

                    WorksheetCell cellNew = row_case.Cells.Add();
                    if (temp.ToLower().Contains("Automation Script Path"))
                        cellNew.Data.Text = testObjParam.AutomationScriptPath;
                    else if (temp.ToLower().Contains("Execution Start Date"))
                        cellNew.Data.Text = testObjParam.ExecutionStartDate;
                    else if (temp.ToLower().Contains("Execution End Date"))
                    {
                        cellNew.Data.Text = DateTime.Now.ToShortDateString() + " " + DateTime.Now.ToShortTimeString();
                        ws.Table.Rows.Add();
                    }

                }

            }
        }

        private void WriteEachScenario (string scenarioCellData, WorksheetRow rowCase)
        {
            WorksheetCell cell = rowCase.Cells.Add();


            string temp = scenarioCellData.ToString();
            if (scenarioCellData.ToString().Contains("\n"))
                temp = temp.Replace("\n", "\r\n");
            
            
            cell.Data.Text = temp;
            
        }

        #endregion

        #endregion

    }
}
